Add URRobotCfg, and dual-arm composition#331
Merged
Merged
Conversation
…s keys in merge_robot_cfg
…uple/validate/dead-solver-set
One RobotCfg subclass switchable via robot_type; DH params owned by URSolverCfg, the robot config owns URDF/control parts/drive props/attrs. Per-variant max_effort scaled by robot size; UR5's lowercase joint names handled explicitly. Routes build_pk_serial_chain through _pk_urdf_path. Also fixes URSolverCfg.class_type (inherited "BaseSolver" -> "URSolver") so the solver can be deserialized from a dict (enables cfg round-trip). Co-Authored-By: Claude <noreply@anthropic.com>
Adds docs/source/resources/robot/ur_robot.md and registers it in resources/robot/index.rst. Adds a __main__ block to ur_robot.py that adds the robot to a sim and checks the to_dict round-trip. Co-Authored-By: Claude <noreply@anthropic.com>
matafela
reviewed
Jun 26, 2026
…ingle-arm robot Generic build_dual_arm_cfg engine + DualArmRobotCfg wrapper that derives a two-arm config (left/right/dual parts, per-arm solver, mirrored drive props) from any single-arm RobotCfg following the "arm" convention — today UR, future Franka via a one-line registry entry. Dict/YAML constructible. Co-Authored-By: Claude <noreply@anthropic.com>
…m robot build_dual_arm_cfg engine + DualArmRobotCfg wrapper derive a two-arm config (left/right/dual control_parts, per-arm solver_cfg, mirrored drive_pros) from any single-arm RobotCfg following the "arm" convention. Today the UR family; future Franka needs only a one-line registry entry — no dual class, no mixin. Two orphan arms mount on a shared base_link via existing URDFCfg assembly; preset+override mounts (side_by_side / facing_inward); dict/YAML constructible and round-trippable. Reuses URSolverCfg arm-local FK/IK (link names stay unprefixed since URSolverCfg pins urdf_path in __post_init__). Tests: 16 new (resolve_mounts, prefixed_name, engine, from_dict/round-trip, PK-DOF drift guard, real dual UR5 URDF assembly name match). No regressions (44 passed incl. existing robot cfg tests). Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds first-class robot configuration support for the Universal Robots UR family via a single URRobotCfg (variant-selected by robot_type), plus a generic dual-arm composition path (DualArmRobotCfg) built on multi-component URDF assembly. The PR also extends URDF assembly naming controls (introducing an "original" casing mode), fixes URSolverCfg deserialization, updates atomic-action tutorials to reuse a shared UR5+gripper config helper, and adds docs + tests around the new robot configs.
Changes:
- Introduce
URRobotCfg(UR3/UR3e/UR5/UR5e/UR10/UR10e) and add UR-family tests (from_dict, round-trip, PK DOF drift guard, effort scaling, unknown type). - Add
DualArmRobotCfg+ builder utilities (resolve_mounts,build_dual_arm_cfg) and a dedicated test suite verifying naming/assembly invariants. - Expand URDF assembly name normalization to support
"original"casing and mergeurdf_cfg.name_casethroughmerge_robot_cfg; update docs/tutorial scripts accordingly.
Reviewed changes
Copilot reviewed 20 out of 29 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
tests/sim/objects/test_robot_cfg.py |
Adds URRobotCfg unit tests (construction, round-trip, PK drift-guard, effort scaling, error case). |
tests/sim/objects/test_dual_arm.py |
New comprehensive tests for dual-arm composition (mount presets, derived names, URDF assembly integration). |
scripts/tutorials/atomic_action/tutorial_utils.py |
Adds create_ur5_gripper_robot_cfg helper and constants; tutorials reuse it. |
scripts/tutorials/atomic_action/place.py |
Switches UR5 robot creation to shared helper, removes duplicated config code. |
scripts/tutorials/atomic_action/pickup.py |
Switches UR5 robot creation to shared helper, removes duplicated config code. |
scripts/tutorials/atomic_action/move_joints.py |
Switches UR5 robot creation to shared helper, removes duplicated config code. |
scripts/tutorials/atomic_action/move_held_object.py |
Switches UR5 robot creation to shared helper, cleans up imports/ordering. |
scripts/tutorials/atomic_action/move_end_effector.py |
Switches UR5 robot creation to shared helper, removes duplicated config code. |
embodichain/toolkits/urdf_assembly/name_normalizer.py |
Adds "original" normalization mode alongside legacy "none". |
embodichain/toolkits/urdf_assembly/connection.py |
Updates docstring to mention "original" mode support. |
embodichain/toolkits/urdf_assembly/component.py |
Updates docstring to mention "original" mode support. |
embodichain/lab/sim/utility/cfg_utils.py |
Merges urdf_cfg.name_case when applying overrides in merge_robot_cfg. |
embodichain/lab/sim/solvers/ur_solver.py |
Fixes URSolverCfg deserialization by setting class_type = "URSolver". |
embodichain/lab/sim/robots/ur_robot.py |
New UR-family RobotCfg subclass with variant-driven URDF + defaults + PK chain builder. |
embodichain/lab/sim/robots/dual_arm.py |
New dual-arm composition engine + wrapper config + PK chain builder. |
embodichain/lab/sim/robots/__init__.py |
Exports URRobotCfg, DualArmRobotCfg, and build_dual_arm_cfg. |
embodichain/lab/sim/cfg.py |
Changes URDFCfg name_case defaults/documentation for casing policy during assembly. |
docs/source/resources/robot/ur_robot.md |
New documentation page for UR family robot config. |
docs/source/resources/robot/dual_arm.md |
New documentation page for dual-arm composition API and presets. |
docs/source/resources/robot/index.rst |
Registers UR family and dual-arm docs pages in the robots index. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1056
to
+1061
| """Case normalization policy applied to joint/link names during URDF assembly. | ||
|
|
||
| Supported values per key are ``"upper"``, ``"lower"`` or ``"original"`` | ||
| (legacy alias ``"none"``). The default upper-cases joints and lower-cases | ||
| links. Set ``{"joint": "original"}`` to preserve the source URDF casing. | ||
| """ |
Comment on lines
24
to
+28
| import torch | ||
|
|
||
| from embodichain.data import get_data_path | ||
| from embodichain.lab.sim import SimulationManager | ||
| from embodichain.lab.sim.cfg import MarkerCfg | ||
| from embodichain.lab.sim.cfg import MarkerCfg, RobotCfg |
Comment on lines
+130
to
+138
| .. attention:: | ||
| :class:`~embodichain.lab.sim.cfg.URDFCfg` defaults to upper-casing joint | ||
| names during multi-component assembly. The override dict passed to | ||
| :meth:`URRobotCfg.from_dict` sets | ||
| ``urdf_cfg.name_case = {"joint": "lower", "link": "lower"}`` so the | ||
| assembled robot keeps the source URDF's lowercase joint names | ||
| (``joint1``..``joint6`` and ``gripper_finger1_joint_1``), matching the | ||
| control parts produced by | ||
| :class:`~embodichain.lab.sim.robots.ur_robot.URRobotCfg`. |
Comment on lines
+22
to
+27
| from embodichain.lab.sim.cfg import ( | ||
| RobotCfg, | ||
| URDFCfg, | ||
| JointDrivePropertiesCfg, | ||
| RigidBodyAttributesCfg, | ||
| ) |
| robot_type: str = "ur10" | ||
|
|
||
| @classmethod | ||
| def from_dict(cls, init_dict): |
Comment on lines
+271
to
+274
| Scalar fields apply to all joints uniformly and are copied verbatim. A | ||
| regex->value dict (per-joint-index drive) is mirrored by uppercasing each | ||
| pattern and emitting ``LEFT_`` / ``RIGHT_`` variants, matching the | ||
| assembled (prefixed) joint names. |
matafela
approved these changes
Jun 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR expands the robot configuration system in three connected parts:
RobotCfgprotocol into the base class so robot configs can build defaults through_build_defaults, round-trip throughfrom_dict/to_dict, and tolerate subclass-specific keys inmerge_robot_cfg.URRobotCfg, a singleRobotCfgsubclass covering the Universal Robots family (ur3,ur3e,ur5,ur5e,ur10,ur10e) throughrobot_type.DualArmRobotCfgorbuild_dual_arm_cfg.What changed
RobotCfg:_build_defaultshook, base serialization flow,_pk_urdf_pathsupport forbuild_pk_serial_chain, and cfg merge support for subclass keys.dexforce_w1andcobotmagic, cleaned up robot exports, and aligned the add-robot docs/context/skill around the new pattern.URRobotCfg: one class for six UR variants, including per-variant URDF selection, joint-name casing, control parts, and scale-aware drive defaults.DualArmRobotCfg,build_dual_arm_cfg, and mount resolution utilities to derive a dual manipulator from a single-arm robot cfg, including optional compositedual_armcontrol parts.URSolverCfgnow declaresclass_type = "URSolver", which fixes deserialization/round-trip through config dicts.Docs
docs/source/resources/robot/ur_robot.md.docs/source/resources/robot/dual_arm.md.docs/source/resources/robot/index.rst.docs/source/_static/robots/.Tests
tests/sim/objects/test_robot_cfg.py.tests/sim/objects/test_dual_arm.py, including control parts, solver behavior, round-trip serialization, PK DOF checks, and assembled UR5 joint-name validation.Dependencies
Type of change
Screenshots
N/A.
Checklist
black .command to format the code base.